package com.gb.config;

import com.gb.models.user.model.SysPermissionEntity;
import com.gb.models.user.model.SysRoleEntity;
import com.gb.models.user.model.SysUserEntity;
import com.gb.models.user.service.SysPermissionService;
import com.gb.models.user.service.SysRoleService;
import com.gb.models.user.service.SysUserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.commons.collections.CollectionUtils;
import javax.annotation.Resource;
import java.util.*;

/**
 * 身份校验核心类
 *
 * @author lgoodbook@163.com
 * @version 1.0.0
 * @Date 2017-08-11 10:33
 */
public class MyShiroRealm extends AuthorizingRealm {

    protected Logger log = LoggerFactory.getLogger(MyShiroRealm.class);

    @Resource
    private SysUserService userService;

    @Resource
    private SysPermissionService permissionService;

    @Resource
    private SysRoleService roleService;

    /**
     * 授权(验证权限时调用)
     * @param
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        log.info("权限认证方法==========：MyShiroRealm.doGetAuthenticationInfo()");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        SysUserEntity userDoInfo = (SysUserEntity) principals.getPrimaryPrincipal();
        log.info("权限："+userDoInfo.getRoles().size());
        //根据用户ID查询角色（role），放入到Authorization里。
        List<SysRoleEntity> roleList = userDoInfo.getRoles();
        Set<String> roleSet = new HashSet<String>();
        Set<String> permissionSet = new HashSet<String>();
        for(SysRoleEntity role : roleList){
            roleSet.add(role.getType());
            for(SysPermissionEntity Permission : role.getPermissions()){
                permissionSet.add(Permission.getUrl());
            }
        }
        log.info("角色："+roleSet +"  权限："+ permissionSet);
        info.setRoles(roleSet);
        info.setStringPermissions(permissionSet);
        return info;
    }

    /**
     * 认证信息(身份验证) Authentication 是用来验证用户身份
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        log.info("身份认证方法：MyShiroRealm.doGetAuthenticationInfo()");
        // 获取用户的输入帐号
        UsernamePasswordToken upToken = (UsernamePasswordToken)token;
        String password = String.valueOf(upToken.getPassword());
        // 通过username从数据库中查找 User对象，如果找到，没找到.
        // 实际项目中，这里可以根据实际情况做缓存，如果不做，Shiro自己也是有时间间隔机制，2分钟内不会重复执行该方法
        SysUserEntity user = userService.queryUserByUsernameAndPassword(upToken.getUsername(), password);
        if(user == null) throw new AccountException("账户或密码不正确!");
        if (user.getStatus() == 0) {
            throw new DisabledAccountException("帐号已经禁止登录！");
        } else {
            user.setLastLoginTime(new Date());
            userService.updateUserById(user);
        }
        return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
    }
}